package com.reyco1.services
{
	/*
	imports
	*/
	import com.reyco1.extension.DispatchExtension;
	import com.reyco1.events.YouTubeEvent;
	import flash.net.URLVariables;
	import flash.net.URLLoaderDataFormat;
	import flash.net.URLLoader;
	import flash.net.URLRequest;
	import flash.events.Event;
	import flash.events.IOErrorEvent;
	
	/*
	class
	*/
	public class YouTube extends DispatchExtension
	{
		/*
		variables
		*/
		private var apiKey:String;
		private var restURL:String;
		private var flvGetURL:String;
		private var proxyURL:String;
		private var videoProxyURL:String;
		private var currentRequest:URLRequest;
		private var currentFlvRequest:URLRequest;
		
		private var videoAPI:String;
		private var videosByCategoryAndTag:String;
		private var videosByUser:String;
		private var videosByTag:String;
		private var videoDetails:String;
		private var videoID:String;
		/*
		class
		*/
		public function YouTube():void
		{
			this.videoAPI = "youtube.videos."
			this.videoID = "videoid"; 
			this.videosByCategoryAndTag = this.videoAPI + "list_by_category_and_tag";
			this.videosByUser = this.videoAPI + "list_by_user";
			this.videosByTag = this.videoAPI + "list_by_tag";
			this.videoDetails = this.videoAPI + "get_details";
			
			this.restURL = "http://www.youtube.com/api2_rest";
			this.flvGetURL = "http://www.youtube.com/get_video?video_id=";
		}
		
		/**
		 * Method which sets up the required variables in order to use your instance of the YouTube service
		 * @param $setupObject : An object with three required values:
		 * 
		 * <ul>
		 * <li><b>key</b> : your YouTube developer key</li>
		 * <li><b>proxy</b> : path to your server side proxy php or aspx file</li>
		 * <li><b>video_proxy</b> : path to your getVideo php or aspx file</li>
		 * </ul>
		 * 
		 */		
		public function setup($setupObject:Object):void
		{
			this.apiKey = $setupObject.key;
			this.proxyURL = $setupObject.proxy + "?url=";
			this.videoProxyURL = $setupObject.video_proxy;
		}
		
		/**
		 * Makes a request to the YouTube servers for a list of videos
		 * @param $requestObject : an object with one of three values:
		 * 
		 * <ul>
		 * <li><b>user</b> : returns a list of videos based on a user</li>
		 * <li><b>tag</b> : returns a list of videos based on a tag</li>
		 * <li><b>category</b> : must be used with <b>tag</b> in order to return tags from a specific category</li>
		 * </ul>
		 * 
		 * <b>categories<b/>
		 * 
		 * <ul>
		 * <li><b>1</b> : Film and animations</li>
		 * <li><b>2</b> : Autos and vehicles</li>
		 * <li><b>23</b> : Commedy</li>
		 * <li><b>24</b> : Entertainement</li>
		 * <li><b>10</b> : Music</li>
		 * <li><b>25</b> : News and politics</li>
		 * <li><b>22</b> : People and blogs</li>
		 * <li><b>15</b> : Pets and animals</li>
		 * <li><b>17</b> : Sports</li>
		 * <li><b>19</b> : Travel and places</li>
		 * <li><b>20</b> : Gadgets and games</li>
		 * </ul>
		 */		
		public function getVideos($requestObject:Object):void
		{
			var requestVariables:URLVariables = new URLVariables();
			requestVariables.dev_id = this.apiKey;
			requestVariables.page = 1;
			requestVariables.per_page = 100;
			
			var user:String = ($requestObject.user) ? $requestObject.user : "";
			var tag:String = ($requestObject.tag) ? $requestObject.tag : "";
			var category:String = ($requestObject.category) ? $requestObject.category : "";
			var type:String = ($requestObject.type) ? $requestObject.type : "";
			
			if(user != ""){		
				requestVariables.method = this.videosByUser;		
				requestVariables.user = user;
			} else if(tag != ""){
				requestVariables.tag = tag;
				if(category != ""){
					requestVariables.method = this.videosByCategoryAndTag;
					requestVariables.category_id = category; // list category ids
				} else{
					requestVariables.method = this.videosByTag;
				}
			}
			
			this.makeRequest(requestVariables);
			//output("requesting video list...");
		}
		
		/**
		 * Makes a request for the flv path of a selected video
		 * @param $id : video id
		 * 
		 */		
		public function requestFLV($id:String):void
		{
			this.currentFlvRequest = new URLRequest(this.videoProxyURL);
			var flvRequestVars:URLVariables = new URLVariables();
			
			flvRequestVars.method = this.videoID;
			flvRequestVars.url = "http://www.youtube.com/watch?v=" + $id
			this.currentFlvRequest.data = flvRequestVars;
			this.currentFlvRequest.method = "GET";
			
			var flvRequestLoader:URLLoader=new URLLoader(this.currentFlvRequest);
			flvRequestLoader.dataFormat = URLLoaderDataFormat.TEXT;

			flvRequestLoader.addEventListener(Event.COMPLETE, onFlvRequestHandler);
			flvRequestLoader.addEventListener(IOErrorEvent.IO_ERROR, onFlvRequestError);
			
			flvRequestLoader.load(this.currentFlvRequest);
			//output("requesting flv...")
		}
		
		private function makeRequest($variables:URLVariables):void
		{
			var requestURL:String = this.proxyURL + this.restURL;
			this.currentRequest = new URLRequest(requestURL);
			
			this.currentRequest.data = $variables;
			this.currentRequest.method = "POST";

			var requestLoader:URLLoader = new URLLoader(this.currentRequest);
			requestLoader.dataFormat = URLLoaderDataFormat.TEXT;

			requestLoader.addEventListener(Event.COMPLETE, onRequestLoaded);
			requestLoader.addEventListener(IOErrorEvent.IO_ERROR, onRequestError);
			
			requestLoader.load(this.currentRequest);
		}
		
		private function onRequestLoaded($event:Event):void
		{
			var requestLoader:URLLoader = $event.target as URLLoader;
			var requestedXML:XML = new XML(requestLoader.data.toString());
			var requestedData:XMLList = requestedXML.video_list.video;
			
			this.dispatchEvent(new YouTubeEvent(YouTubeEvent.REQUEST_COMPLETE, {data:requestedData}));	
			//output("video list received.")		
		}
		
		private function onFlvRequestHandler($event:Event):void
		{
			var flvRequestLoader:URLLoader = $event.target as URLLoader;
			var requestedXML:XML = new XML(flvRequestLoader.data.toString());
			var path:String = this.flvGetURL + requestedXML.id + "&t=" + requestedXML.t;
			
			this.dispatchEvent(new YouTubeEvent(YouTubeEvent.FLV_REQUEST_COMPLETE, {path:path}));
			//output("flv path received.")
		}
		
		private function onFlvRequestError($event:IOErrorEvent):void
		{
			this.dispatchEvent(new YouTubeEvent(YouTubeEvent.FLV_REQUEST_ERROR, {}));
		}
		
		private function onRequestError($event:IOErrorEvent):void
		{
			this.dispatchEvent(new YouTubeEvent(YouTubeEvent.REQUEST_ERROR, {}));	
		}
		
	}
}